package com.spring.common.util;


import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Copyright: Shanghai Definesys Company.All rights reserved.
 * @Description: JWT 保存用户信息
 * @author: chuhaitao
 * @since: 2019/3/17 10:18
 * @history: 1.2019/3/17 created by chuhaitao
 */
public class JWTUtil {


    private static final String SECRET_KEY = "123456789";
    /**
     * 过期时间
     */
    private static final Long TT_MILLIS = 1000 * 60 * 60 * 6L;


    /**
     * 创建加密的jwt信息
     *
     * @param subject
     * @param obj
     * @param
     * @return
     */
    public static String createJWT(String subject, Object obj) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        JwtBuilder builder = Jwts.builder()
                .setSubject(subject)
                .claim("user", obj)
                .signWith(signatureAlgorithm, SECRET_KEY);

        if (TT_MILLIS >= 0) {
            long expMillis = System.currentTimeMillis() + TT_MILLIS;
            builder.setExpiration(new Date(expMillis));
        }
        return builder.compact();
    }


    /**
     * 验证token是否失效
     *
     * @param jwtStr
     * @return
     */
    public static Boolean validateJWT(String jwtStr) {
        Claims claims = null;
        try {
            claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(jwtStr).getBody();
        } catch (Exception e) {
            e.getMessage();
            return false;
        }
        return true;
    }


    /**
     * 从token中解析用户的信息
     *
     * @param jwtStr
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getObjectFromToken(String jwtStr, Class<T> clazz) {
        Claims claims = Jwts
                .parser()
                .setSigningKey(SECRET_KEY).parseClaimsJws(jwtStr)
                .getBody();

        HashMap<String, Object> tokenMap = (HashMap<String, Object>) claims.get("user");

        return mapToBean(tokenMap, clazz);

    }


    private static <T> T mapToBean(Map<String, Object> tokenMap, Class<T> clazz) {
        T obj = null;
        BeanInfo beanInfo = null;
        try {
            obj = clazz.newInstance();
            beanInfo = Introspector.getBeanInfo(clazz);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                if (tokenMap.containsKey(key)) {
                    Object value = tokenMap.get(key);
                    Method setter = property.getWriteMethod();
                    setter.invoke(obj, value);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;

    }


}
